﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using ConcreteMappersAndObjects.DomainObjects;
using DataMappers;
using System.Data;


namespace ConcreteMappersAndObjects.Mappers
{
    public class ClassesDataMapper : AbstractDataMapper<int, SClass>
    {
        public IEntityMapper<int, Regime> _regimeMapper;
        public IEntityMapper<int, Course> _courseMapper;
        public IEntityMapper<TeacherClassCUnitKey, TeacherClassCUnit> _tccuMapper;


        public void SetRegimeMapper(IEntityMapper<int, Regime> mapper) { _regimeMapper = mapper; }
        protected override int GetKeyFrom(System.Data.SqlClient.SqlDataReader sdr)
        {
            return sdr.GetInt32(0);
        }

        protected override string DoGetAllStatement()
        {
            return "select ID, Name, RegimeID, CourseID from Class";
        }

        protected override string DoGetFindStatement()
        {
            return DoGetAllStatement() + " where ID = @ID";
        }

        protected override void BindFindStatement(System.Data.SqlClient.SqlCommand cmd, int key)
        {
            cmd.Parameters.AddWithValue("@ID", key);
        }

        private class ClassFilter : IFilter
        {
            private int _classKey;
            public ClassFilter(int classKey)
            {
                _classKey = classKey;
            }

            #region IFilter members

            public string GetWhereClause()
            {
                return " where ClassID = @ClassID";
            }

            public void BindValues(System.Data.SqlClient.SqlCommand cmd)
            {
                cmd.Parameters.AddWithValue("@ClassId", _classKey);
            }

            #endregion
        }


        protected override SClass DoLoad(System.Data.SqlClient.SqlDataReader sdr)
        {
            int key = GetKeyFrom(sdr);
            ConcreteValueHolder<int, Regime> regime = new ConcreteValueHolder<int,Regime>(sdr.GetInt32(2), _regimeMapper);
            ConcreteValueHolder<int, Course> course = new ConcreteValueHolder<int,Course>(sdr.GetInt32(3), _courseMapper);
            LazySet<TeacherClassCUnitKey, TeacherClassCUnit> tccu = new LazySet<TeacherClassCUnitKey,TeacherClassCUnit>(_tccuMapper, new ClassFilter(key));
            return new SClass(key, sdr.GetString(1), regime, course, tccu);
        }

        protected override string GetUpdateCommand()
        {
            return "update Class set Name = @Name, RegimeID = @RegimeID, CourseID = @CourseID where ID = @ID";
        }

        protected override void DoBindUpdate(System.Data.SqlClient.SqlCommand cmd, SClass t)
        {
            cmd.Parameters.Add("@Name", SqlDbType.NVarChar, 10).Value = t.Name;
            cmd.Parameters.Add("@RegimeID", SqlDbType.Int).Value = t.Regime.ID;
            cmd.Parameters.Add("@CourseID", SqlDbType.Int).Value = t.Course.ID;
            cmd.Parameters.Add("@ID", SqlDbType.Int).Value = t.ID;
        }

        protected override string GetInsertCommand()
        {
            return "ClassInsert";
        }

        protected override void DoBindInsert(System.Data.SqlClient.SqlCommand cmd, SClass t)
        {
            cmd.CommandType = CommandType.StoredProcedure;
            cmd.Parameters.Add("@Name", SqlDbType.NVarChar, 20).Value = t.Name;
            cmd.Parameters.Add("@RegimeID", SqlDbType.Int).Value = t.Regime != null ? (object)t.Regime.ID : DBNull.Value;
            cmd.Parameters.Add("@CourseID", SqlDbType.Int).Value = t.Course != null? (object)t.Course.ID : DBNull.Value;
        }

        protected override string GetRemoveCommand()
        {
            return "delete from Class Where ID = @ID";
        }

        protected override void DoBindRemove(System.Data.SqlClient.SqlCommand cmd, SClass t)
        {
            cmd.Parameters.Add("@ID", SqlDbType.Int).Value = t.ID;
        }

        protected override void FinishUpdateObject(SClass t)
        {
            throw new NotImplementedException();
        }

        protected override void FinishNewObject(SClass t, object id)
        {
            t.ID = Convert.ToInt32(id);
        }

        protected override void FinishDeleteObject(SClass t)
        {
            
        }
    }
}
